package editor;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import javax.swing.JTextArea;
import org.agilelang.config.AgileConfig;
import org.agilelang.config.AgileStructure;
import org.agilelang.config.AgileSyntax;
import org.agilelang.config.FileStatic;
import org.agilelang.config.ReadConfig;
import org.agilelang.config.ScannerConfig;
import org.agilelang.generate.AgileGenerator;
import org.agilelang.generate.UtilFile;
import org.agilelang.scanner.Scanner;

/**
 *
 * @author RoderickNestor
 */
public class Generate {

    Editor editor;

    public Generate(Editor editor) {
        this.editor = editor;
    }

    private Generate() {
       
    }

    void generate(String path) {

        String folder_tmp = "tmp";
        String folder_static = "static";
        String folder_tmpl = "tmpl";
        String folder_source = "source";
        String folder_config = "config";

        File tmp = new File(path + File.separator + folder_tmp);
        if (!tmp.exists()) {
            if (tmp.mkdir()) {
                System.out.println("Directorio temporal creado : " + path + File.separator + folder_tmp);
            } else {
                System.err.println("Error no se puede crear directorio temporal");
            }
        } else {
            System.out.println("Directorio temporal ya existe : " + path + File.separator + folder_tmp);
        }

        tmp = new File(path + File.separator + folder_static);
        if (!tmp.exists()) {
            if (tmp.mkdir()) {
                System.out.println("Directorio statico creado : " + path + File.separator + folder_static);
            } else {
                System.err.println("Error no se puede crear directorio statico");
            }
        } else {
            System.out.println("Directorio statico ya existe : " + path + File.separator + folder_static);
        }
        //----------------------------------------------------------------------

        File file_config = new File(path + File.separator + folder_config);
        String lineFromFile_config = "";
        for (File file : file_config.listFiles()) {
            System.out.println("Generate : " + file.getAbsolutePath());
            if (file.getName().endsWith(".config")) {
                Path newFile = Paths.get(file.getAbsolutePath());
                try (BufferedReader reader = Files.newBufferedReader(
                        newFile, Charset.defaultCharset())) {
                    String lineFromFile = "";
                    System.out.println("The contents of file are: ");
                    while ((lineFromFile = reader.readLine()) != null) {
                        System.out.println(lineFromFile);
                        lineFromFile_config += lineFromFile + "\n";
                    }

                } catch (IOException exception) {
                    System.out.println("Error while reading file");
                }
            }
        }

        //Create a new Path
        Path newFile = Paths.get(path + File.separator + folder_tmp + File.separator + "out_config");
        try {
            Files.deleteIfExists(newFile);
            newFile = Files.createFile(newFile);
        } catch (IOException ex) {
            System.out.println("Error creating file");
        }
        System.out.println(Files.exists(newFile));
        //Writing to file4
        try (BufferedWriter writer = Files.newBufferedWriter(
                newFile, Charset.defaultCharset())) {
            writer.append(lineFromFile_config);

            writer.flush();
        } catch (IOException exception) {
            System.out.println("Error writing to file");
        }

        //editor.panelSouth.appendDebug("Scanning configuration files");
        ScannerConfig scanner_config = new ScannerConfig(path + File.separator + folder_tmp + File.separator + "out_config",
                path + File.separator + folder_tmp + File.separator + "config_out.xml");

        //----------------------------------------------------------------------
        ReadConfig read_config = new ReadConfig();
        read_config.process(path + File.separator + folder_tmp + File.separator + "config_out.xml");
        AgileConfig aconfig = read_config.getAconfig();
        AgileStructure astructure = read_config.getAstructure();
        HashMap<String, AgileSyntax> hashAgileSyntax = read_config.getHashAgileSyntax();
        //----------------------------------------------------------------------
        //----------------------------------------------------------------------
        List<String> folders = astructure.folder;
        for (String folder : folders) {
            File file_folder = new File(aconfig.folderOut + File.separator + folder);
            if (!file_folder.exists()) {
                if (file_folder.mkdir()) {
                    //editor.panelSouth.appendDebug("Directorio creado : " + file_folder.getAbsolutePath());
                } else {
                    //editor.panelSouth.appendDebug("Error no se puede crear directorio : " + file_folder.getAbsolutePath());
                }
            } else {
                //editor.panelSouth.appendDebug("Directorio ya existe : " + file_folder.getAbsolutePath());
            }
        }
        //----------------------------------------------------------------------
        List<FileStatic> files = astructure.file;
        for (FileStatic archive : files) {
            File file_archive = new File(path + File.separator + folder_static + File.separator + archive.input);
            if (file_archive.exists()) {
                String content = UtilFile.readFile(path + File.separator + folder_static + File.separator + archive.input);
                UtilFile.writefile(aconfig.folderOut + File.separator + archive.output, content);
                //editor.panelSouth.appendDebug("Copiar archivo : " + aconfig.folderOut + File.separator + archive.output);
            } else {
                //editor.panelSouth.appendDebug("No se encuentra archivo  : " + path + File.separator + folder_static + File.separator + archive.input);
            }
        }
        List<FileStatic> zips = astructure.zip;
        for (FileStatic zip : zips) {
            File file_archive = new File(aconfig.folderResource + File.separator + zip.input);
            if (file_archive.exists()) {
                UtilFile.unzip(aconfig.folderResource + File.separator + zip.input, aconfig.folderOut + File.separator + zip.output);

                //editor.panelSouth.appendDebug("Copiar archivo : " + aconfig.folderOut + File.separator + zip.output);
            } else {
               // editor.panelSouth.appendDebug("No se encuentra archivo  : " + path + File.separator + folder_static + File.separator + zip.input);
            }
        }
        //----------------------------------------------------------------------
        File file_source = new File(path + File.separator + folder_source);
        String lineFromFile_source = "";
        for (File file : file_source.listFiles()) {

            if (file.getName().endsWith(".agile")) {
                System.out.println("Read file source : " + file.getAbsolutePath());

                Path path_file_source = Paths.get(file.getAbsolutePath());
                try (BufferedReader reader_file_source = Files.newBufferedReader(
                        path_file_source, Charset.defaultCharset())) {
                    String lineFromFile = "";
                    System.out.println("The contents of file are: ");
                    while ((lineFromFile = reader_file_source.readLine()) != null) {
                        System.out.println(lineFromFile);
                        lineFromFile_source += lineFromFile + "\n";;
                    }

                } catch (IOException exception) {
                    System.out.println("Error while reading file"
                            + exception.toString());
                }
            }
        }

        //Create a new Path
        Path newFile1 = Paths.get(path + File.separator + folder_tmp + File.separator + "out_source");
        try {
            Files.deleteIfExists(newFile1);
            newFile1 = Files.createFile(newFile1);
        } catch (IOException ex) {
            System.err.println("Error creating file");
        }
        System.out.println(Files.exists(newFile1));
        //Writing to file4
        try (BufferedWriter writer = Files.newBufferedWriter(
                newFile1, Charset.defaultCharset())) {
            writer.append(lineFromFile_source);

            writer.flush();
        } catch (IOException exception) {
            System.out.println("Error writing to file");
        }
        //editor.panelSouth.appendDebug("Scanning source files");

        Scanner scanner = new Scanner(path + File.separator + folder_tmp + File.separator + "out_source",
                read_config.getListObjectClass(), path + File.separator + folder_tmp + File.separator + "scanner_out.xml");
        //----------------------------------------------------------------------
        AgileGenerator ag = new AgileGenerator();
        //editor.panelSouth.appendDebug("Generating files");
        ag.process(path + File.separator + folder_tmp + File.separator + "scanner_out.xml",
                path + File.separator + aconfig.folderTemplate,
                aconfig.folderOut, read_config.getListObjectClass(), new JTextArea());//editor.panelSouth.getDebug()
    }

    public static void copyfile(String srFile, String dtFile) {
        try {

            File f1 = new File(srFile);
            File f2 = new File(dtFile);
            InputStream in = new FileInputStream(f1);

            //For Append the file.
//  OutputStream out = new FileOutputStream(f2,true);
            //For Overwrite the file.
            OutputStream out = new FileOutputStream(f2);

            byte[] buf = new byte[1024];
            int len;
            while ((len = in.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
            in.close();
            out.close();
            System.out.println("File copied.");
        } catch (FileNotFoundException ex) {
            System.out.println(ex.getMessage() + " in the specified directory.");
            System.exit(0);
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }
    
    
    public static void main(String ar[]) {
        
        Generate generate = new Generate();
        //generate.generate("E:\\agile\\Ejemplos\\EjemploJavaCRUD");
        generate.generate("E:\\agile\\Ejemplos\\laravel");
        
    }
}
